﻿using UnityEngine;
using System;
using System.Collections.Generic;
namespace Room
{
    class MeshFrameAnimation:MonoBehaviour
    {
        private MeshFilter meshFilter;

        private GameObject model;
        private Transform leftWeapon;
        private Transform rightWeapon;
        
        private string modelName;
        private float length = 0;
        private float rate = 2;

        
        private SkinnedMeshRenderer modelSkinMesh;
        private Animation modelAnimation;
        private ModelRenderKit modelRenderKit;

        private MeshFilter dstMeshFilter;

        private string animName = "";
        private float animTime = 0;

        public void Init(GameObject model, MeshFilter meshFilter,string modelName,Transform leftWeapon,Transform rightWeapon)
        {
            this.model = model;
            this.modelName = modelName;
            this.leftWeapon = leftWeapon;
            this.rightWeapon = rightWeapon;
            dstMeshFilter = meshFilter;
            modelAnimation = model.GetComponent<LegacyAnimation>().anim;
            modelRenderKit = model.GetComponent<ModelRenderKit>();
            modelSkinMesh = modelRenderKit.skinnedMeshRenderer;

            RoomMeshFramePool.Instance.RetainModel(modelName);
        }

        public void Play(string animName)
        {
            if(this.animName.Equals(animName))
            {
                return;
            }
            this.animName = animName;
            animTime = 0;
            length = modelAnimation[animName].length;
            int frameCount = (int)Math.Floor(length * rate)+1;
            RoomMeshFramePool.Instance.CreateAnimation(modelName, animName, frameCount);
        }

        void Update()
        {
            animTime += Time.deltaTime;
            if (animTime > length)
            {
                animTime = 0;
            }
            int frame = (int)Math.Floor(animTime * rate);
            var cacheFrame = RoomMeshFramePool.Instance.GetFrame(modelName, animName, frame);
            if (cacheFrame == null)
            {
                modelAnimation[animName].time = animTime;
                modelAnimation[animName].enabled = true;
                modelAnimation[animName].weight = 1;
                modelAnimation.Sample();
                modelAnimation[animName].enabled = false;

                cacheFrame = new CacheFrame();
                cacheFrame.mesh = new Mesh();
                modelSkinMesh.BakeMesh(cacheFrame.mesh);
                //Transform
                var rootMatInverse = model.transform.localToWorldMatrix.inverse;
                var rotateMat = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), model.transform.localScale);

                cacheFrame.leftMatrix = rotateMat * rootMatInverse * modelRenderKit.GetWuqiTransform(true).localToWorldMatrix;
                cacheFrame.rightMatrix = rotateMat * rootMatInverse * modelRenderKit.GetWuqiTransform(false).localToWorldMatrix;

                RoomMeshFramePool.Instance.PutFrame(modelName, animName, frame, cacheFrame);

            }
            dstMeshFilter.mesh = cacheFrame.mesh;
            leftWeapon.localPosition = CommonMethod.ExtractTranslationFromMatrix(ref cacheFrame.leftMatrix);
            leftWeapon.localRotation = CommonMethod.ExtractRotationFromMatrix(ref cacheFrame.leftMatrix);
            leftWeapon.localScale = CommonMethod.ExtractScaleFromMatrix(ref cacheFrame.leftMatrix);
            rightWeapon.localPosition = CommonMethod.ExtractTranslationFromMatrix(ref cacheFrame.rightMatrix);
            rightWeapon.localRotation = CommonMethod.ExtractRotationFromMatrix(ref cacheFrame.rightMatrix);
            rightWeapon.localScale = CommonMethod.ExtractScaleFromMatrix(ref cacheFrame.rightMatrix);
        }

        void OnDestroy()
        {
            if(modelName!=null)
            {
                RoomMeshFramePool.Instance.ReleaseModel(modelName);
            }
        }
    }
}
